package com.ambercrm.http;

import com.ambercrm.business.bean.UploadImageBean;
import com.ambercrm.common.Common;
import com.ambercrm.constant.UrlConstant;
import com.ambercrm.eventbus_event.LogoutEvent;
import com.ambercrm.http.download.FileItem;
import com.ambercrm.tools.LogUtils;
import com.ambercrm.tools.ToastUtils;
import com.google.gson.Gson;
import com.yanzhenjie.kalle.Binary;
import com.yanzhenjie.kalle.BodyRequest;
import com.yanzhenjie.kalle.Canceller;
import com.yanzhenjie.kalle.FileBinary;
import com.yanzhenjie.kalle.FormBody;
import com.yanzhenjie.kalle.JsonBody;
import com.yanzhenjie.kalle.Kalle;
import com.yanzhenjie.kalle.Params;
import com.yanzhenjie.kalle.ProgressBar;
import com.yanzhenjie.kalle.RequestMethod;
import com.yanzhenjie.kalle.Response;
import com.yanzhenjie.kalle.UrlRequest;
import com.yanzhenjie.kalle.connect.http.Call;
import com.yanzhenjie.kalle.download.Download;
import com.yanzhenjie.kalle.exception.ConnectTimeoutError;
import com.yanzhenjie.kalle.exception.HostError;
import com.yanzhenjie.kalle.exception.NetworkError;
import com.yanzhenjie.kalle.exception.ReadTimeoutError;
import com.yanzhenjie.kalle.exception.URLError;
import com.yanzhenjie.kalle.exception.WriteException;
import com.yanzhenjie.kalle.simple.Callback;
import com.yanzhenjie.kalle.simple.SimpleCallback;
import com.yanzhenjie.kalle.simple.SimpleResponse;

import org.json.JSONObject;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

import de.greenrobot.event.EventBus;

public class HttpUtils {
    static Gson mGons = new Gson();

    // 普通的Get Post请求的回调监听
    public interface OnResponseListener {
        void onSucceed(String result, int what); // 请求成功回调

        void onFailed(String result, int what); // 请求失败回调

        void onFinish(int what);   // 请求完成回调
    }

    public interface OnDownloadFileResponseListener {
        void onStart();

        void onFailed(String result); // 请求失败回调

        void onFinish(String path);   // 请求完成回调

        void onProgress(int progress); // 进度
    }

    public static void httpGet(String url, HashMap<String, String> params, final OnResponseListener onResponseListener, final int what) {
        String token = Common.getInstance().getToken();
        url = UrlConstant.baseUrl + url;
        url = getUrl(url, params);
        LogUtils.showLog(url);

        Kalle.get(url)
                .addHeader("Authorization", token == null ? "" : ("" + token)) // 添加请求头。
//                .setHeader("name", "kalle") // 设置请求头，会覆盖默认头和之前添加的头。
//                .param("name", "kalle") // 添加请求参数。
                .perform(new Callback<String, String>() {
            @Override
            public void onStart() {

            }

            @Override
            public void onResponse(SimpleResponse<String, String> response) {
                if (response.code() == 200) {
                    String result = response.succeed();
                    LogUtils.showLog(result);
                    if (onResponseListener != null) {
                        onResponseListener.onSucceed(result, what);
                        onResponseListener.onFinish(what);
                    }
                }
                else {
                    if (response.code() == 401) {
                        // 登录过期， 给主页发广播，跳转到登录界面
                        LogUtils.showLog("请求code： 401");
                        EventBus.getDefault().post(new LogoutEvent("logout"));
                        return;
                    }
                    else {
                        try {
                            LogUtils.showLog(response.succeed());
                            JSONObject obj = new JSONObject(response.succeed());
                            if (!obj.isNull("message")) {
                                String msg = obj.getString("message");

                                LogUtils.showLog("请求code：" + response.code());
                                if (onResponseListener != null) {
                                    onResponseListener.onFailed(msg, what);
                                    onResponseListener.onFinish(what);
                                }
                            }
                            else {
                                if (onResponseListener != null) {
                                    onResponseListener.onFailed("系统错误", what);
                                    onResponseListener.onFinish(what);
                                }
                            }
                        }
                        catch (Exception e) {
                            if (onResponseListener != null) {
                                onResponseListener.onFailed(e.toString(), what);
                                onResponseListener.onFinish(what);
                            }
                        }
                    }
                }
            }

            @Override
            public void onException(Exception e) {
                LogUtils.showLog(e.toString());
                String message = null;
                if (e instanceof NetworkError) {
                    message = "网络不可用，请检查网络";
                } else if (e instanceof URLError) {
                    message = "Url格式错误";
                } else if (e instanceof HostError) {
                    message = "没有找到Url指定的服务器";
                } else if (e instanceof ConnectTimeoutError) {
                    message = "连接服务器超时";
                } else if (e instanceof WriteException) {
                    message = "发送数据失败";
                } else if (e instanceof ReadTimeoutError) {
                    message = "读取数据超时";
                } else {
                    message = "发生未知异常";
                }

                if (onResponseListener != null) {
                    if (message == null) {
                        onResponseListener.onFailed(e.toString(), what);
                    } else {
                        onResponseListener.onFailed(message, what);
                    }
                    onResponseListener.onFinish(what);
                }
            }

            @Override
            public void onCancel() {

            }

            @Override
            public void onEnd() {
                if (onResponseListener != null) {
                    onResponseListener.onFinish(what);
                }
            }
        });
    }

    // Get同步请求     .param里面的参数都会拼到url后面去    http://xxxx?name=dongjie&password=123
    public static String httpGetSync(String url, HashMap<String, Object> params) {
        try {
            url = UrlConstant.baseUrl + url;
            UrlRequest urlRequest = UrlRequest.newBuilder(url, RequestMethod.GET) // 这里也可以是post
                    .addHeader("token", "aaaaaaaaaaaa")
                    .param("name", "dongjie")
                    .param("password", "123")
                    .build();
            Response response = new Call(urlRequest).execute();
            return response.body().string();
        }
        catch (Exception e) {

        }

        return null;
    }

    // params 可以是map，也可以是对象
    public static void httpPost(String url, Object params, final OnResponseListener onResponseListener, final int what) {
        String token = Common.getInstance().getToken();
        url = UrlConstant.baseUrl + url;
        LogUtils.showLog(url);
        LogUtils.showLog("请求参数：" + mGons.toJson(params));
        Kalle.post(url)
                .addHeader("Authorization", token == null ? "" : (token)) // 添加请求头。
//                .setHeader("name", "kalle") // 设置请求头，会覆盖默认头和之前添加的头。
//                .param("name", "kalle") // 添加请求参数
                .body(new JsonBody(mGons.toJson(params == null ? new HashMap<String, String>():params))) // 给后台传参数
                .setParams(Params.newBuilder().build())
                .addHeader("Content-Type", "application/json")
                .perform(new Callback<String, String>() {
            @Override
            public void onStart() {

            }

            @Override
            public void onResponse(SimpleResponse<String, String> response) {
                if (response.code() == 200) {
                    String result = response.succeed();
                    LogUtils.showLog("请求结果：" + result);
                    if (onResponseListener != null) {
                        onResponseListener.onSucceed(result, what);
                        onResponseListener.onFinish(what);
                    }
                }
                else {
                    LogUtils.showLog("请求code： " + response.code());
                    if (response.code() == 401) {
                        // 登录过期， 给主页发广播，跳转到登录界面
                        EventBus.getDefault().post(new LogoutEvent("logout"));
                        return;
                    }
                    else {
                        try {
                            LogUtils.showLog(response.succeed());
                            JSONObject obj = new JSONObject(response.succeed());
                            if (!obj.isNull("message")) {
                                String msg = obj.getString("message");
                                if (onResponseListener != null) {
                                    onResponseListener.onFailed(msg, what);
                                    onResponseListener.onFinish(what);
                                }
                            }
                            else {
                                if (onResponseListener != null) {
                                    onResponseListener.onFailed("系统错误", what);
                                    onResponseListener.onFinish(what);
                                }
                            }
                        }
                        catch (Exception e) {
                            if (onResponseListener != null) {
                                onResponseListener.onFailed(e.toString(), what);
                                onResponseListener.onFinish(what);
                            }
                        }
                        return;
                    }
                }
            }

            @Override
            public void onException(Exception e) {
                LogUtils.showLog(e.toString());

                String message = null;
                if (e instanceof NetworkError) {
                    message = "网络不可用，请检查网络";
                } else if (e instanceof URLError) {
                    message = "Url格式错误";
                } else if (e instanceof HostError) {
                    message = "没有找到Url指定的服务器";
                } else if (e instanceof ConnectTimeoutError) {
                    message = "连接服务器超时";
                } else if (e instanceof WriteException) {
                    message = "发送数据失败";
                } else if (e instanceof ReadTimeoutError) {
                    message = "读取数据超时";
                }

                if (onResponseListener != null) {
                    if (message == null) {
                        onResponseListener.onFailed(e.toString(), what);
                    } else {
                        onResponseListener.onFailed(message, what);
                    }
                    onResponseListener.onFinish(what);
                }
            }

            @Override
            public void onCancel() {

            }

            @Override
            public void onEnd() {
                if (onResponseListener != null) {
                    onResponseListener.onFinish(what);
                }
            }
        });
    }

    // Post同步请求，BodyRequest会把.param放到body里传，会把urlParam拼到url的后面
    public static String httpPostSync(String url, String params) {
        try {
            LogUtils.showLog(mGons.toJson(params == null ? new HashMap<String, String>():params));
            String token = Common.getInstance().getToken();
            url = UrlConstant.baseUrl + url;
            LogUtils.showLog(url);
            BodyRequest bodyRequest = BodyRequest.newBuilder(url, RequestMethod.POST)    // 这里可以是get也可以是post
                    .addHeader("Content-Type", "application/json")
                    .addHeader("Authorization", token == null ? "" : (token)) // 添加请求头。
                    .body(new JsonBody(params == null ? "" : params)) // 给后台传参数
                    .build();
            Response response = new Call(bodyRequest).execute();
//            LogUtils.showLog(response.body().string());
            return response.body().string();
        }
        catch (Exception e) {
            LogUtils.showLog(e.toString());
        }

        return null;
    }

    public interface OnImgUploadListener {
        void onUploadResult(String json);
    }

    public static void uploadImg(String url, String imgPath, final OnImgUploadListener listener) {
        String token = Common.getInstance().getToken();
        url = UrlConstant.baseUploadUrl + url;
        LogUtils.showLog(url);

        FileBinary fileBinary = new FileBinary(new File(imgPath));
        fileBinary.onProgress(new ProgressBar<FileBinary>() {
            @Override
            public void progress(FileBinary origin, int progress) {

            }
        });

        FormBody formBody = FormBody.newBuilder().binary("file", fileBinary).build();
        formBody.onProgress(new ProgressBar<FormBody>() {
            @Override
            public void progress(FormBody origin, int progress) {
                // 整体进度
            }
        });

        Kalle.post(url)
                .body(formBody)
//                .addHeader("Authorization", token == null ? "" : ("Bearer " + token)) // 添加请求头。
                .addHeader("Authorization", token == null ? "" : (token)) // 添加请求头。
                .perform(new SimpleCallback<String>() {
                    @Override
                    public void onResponse(SimpleResponse<String, String> response) {
                        if (response.isSucceed()) {
                            LogUtils.showLog("上传完成：" + response.succeed());
                            if (listener != null) {
                                listener.onUploadResult(response.succeed());
                            }
                        } else {
                            ToastUtils.showToast("上传失败：" + response.failed());
                        }
                    }
                });
    }












    static class CustomBinary extends FileBinary {
        public CustomBinary(File file) {
            super(file);
        }

        int what;

        public int getWhat() {
            return what;
        }

        public void setWhat(int what) {
            this.what = what;
        }
    }

    public static void uploadFiles(String url, final ArrayList<FileItem> fileList, final OnResponseListener responseListener) {
        url = UrlConstant.baseUrl + url;
        ArrayList<Binary> binaryArrayList = new ArrayList<>();

        for (int i = 0; i < fileList.size(); i++) {
            CustomBinary binary = new CustomBinary(new File(fileList.get(i).getUrl()));
            binary.setWhat(i);
            binary.onProgress(new ProgressBar<FileBinary>() {
                @Override
                public void progress(FileBinary origin, int progress) {
                    CustomBinary cusBinary = (CustomBinary) origin;
                    LogUtils.showLog("第" + cusBinary.getWhat() + "个文件进度:" + progress);
                    int pos = cusBinary.getWhat();
                    fileList.get(pos).setPosition(pos);
                    fileList.get(pos).setProgress(progress);
                }
            });

            binaryArrayList.add(binary);
        }

        FormBody formBody = FormBody.newBuilder()
                .binaries("file", binaryArrayList)
                .build();
        formBody.onProgress(new ProgressBar<FormBody>() {
            @Override
            public void progress(FormBody origin, int progress) {
                // 这里是整体进度
                LogUtils.showLog("整体进度：" + progress);
            }
        });
        String token = Common.getInstance().getToken();
        Kalle.post(url)
                .body(formBody)
                .addHeader("Authorization", token == null ? "" : ("Bearer " + token)) // 添加请求头。
                .perform(new SimpleCallback<String>() {
            @Override
            public void onResponse(SimpleResponse<String, String> response) {
                if (response.isSucceed()) {
                    LogUtils.showLog("上传完成：" + response.succeed());
                    if (responseListener != null) {
                        responseListener.onSucceed(response.succeed(), 0);
                    }
                } else {
                    if (responseListener != null) {
                        responseListener.onFailed(response.failed(), 0);
                    }
                }
                if (responseListener != null) {
                    responseListener.onFinish(0);
                }
            }
        });
    }

    /*
     * 如果支持断点续传mCanceller.cancel()表示暂停，下次会继续下载
     */
    static Canceller mCanceller;
    public static void downloadOneFile(String url, final OnDownloadFileResponseListener onDownloadFileResponseListener, String dirPath, String fileName) {
//        url = BuildConfig.BaseUrl + url;
        if (mCanceller != null) {
            mCanceller.cancel();
        }
        else {
            mCanceller = Kalle.Download.get(url)
                    .directory(dirPath)
                    .fileName(fileName)
                    .onProgress(new Download.ProgressBar() {
                        @Override
                        public void onProgress(int progress, long byteCount, long speed) {
                            LogUtils.showLog("progress:" + progress);
                            if (onDownloadFileResponseListener != null) {
                                onDownloadFileResponseListener.onProgress(progress);
                            }
                        }
                    })
                    .perform(new com.yanzhenjie.kalle.download.SimpleCallback() {
                        @Override
                        public void onStart() {
                            if (onDownloadFileResponseListener != null) {
                                onDownloadFileResponseListener.onStart();
                            }
                        }

                        @Override
                        public void onException(Exception e) {
                            super.onException(e);
                            mCanceller = null;
                            if (onDownloadFileResponseListener != null) {
                                onDownloadFileResponseListener.onFailed(e.toString());
                            }
                        }

                        @Override
                        public void onFinish(String path) {
                            mCanceller = null;
                            if (onDownloadFileResponseListener != null) {
                                onDownloadFileResponseListener.onFinish(path);
                            }
                        }

                        @Override
                        public void onCancel() {
                            mCanceller = null;
                        }
                    });
        }
    }

    // 组拼get参数
    private static String getUrl(String url, HashMap<String, String> params) {
        // 添加url参数
        if (params != null) {
            Iterator<String> it = params.keySet().iterator();

            StringBuffer stringBuffer = null;

            while (it.hasNext()) {
                String key = it.next();
                String value = params.get(key);

                if (stringBuffer == null) {
                    stringBuffer = new StringBuffer();
                    stringBuffer.append("?");
                } else {
                    stringBuffer.append("&");
                }

                stringBuffer.append(key);
                stringBuffer.append("=");
                stringBuffer.append(value);
            }

            url += stringBuffer.toString();
        }

        return url;
    }
}
